<?php


namespace app\miniapp\controller;


use app\common\cachemodel\MiniAppUser;
use app\common\lib\exception\ApiException;
use app\common\model\User;
use think\Controller;

class AuthCheck extends Controller
{

    public $user = null;
    public $miniInfo = null;
    public $simulationLogin = false; // 是否账号模拟登陆

    /**
     * @return bool-
     * @throws ApiException
     */
    public function isLogin()
    {
        $headers = $this->request->header();
        if (!isset($headers['access-token']) || empty($headers['access-token'])) return false;
        // access-token AES解密
        $accessUserToken = $this->decryptWithOpenssl($headers['access-token']);

        if (empty($accessUserToken)) return false;

        if (!preg_match('/||/', $accessUserToken)) return false;

        [$token, $miniId] = explode('||', $accessUserToken);

        $miniInfo = (new MiniAppUser())->getMiniAppInfo($miniId);

        if (!$miniInfo || ($miniInfo && $miniInfo['access_token'] !== $token) || $this->request->time() > $miniInfo['expires_in'] || $miniInfo['status'] != 0)
        {   // 判断token是否过期 并且账户状态正常
            throw new ApiException('登录失效', 200, config('code.denied'));
        }

        $this->miniInfo = $miniInfo;

        $id = (int)($miniInfo['uid']);
        if (!$id)
        {
            $model = $this->request->module();
            $controller = $this->request->controller();
            $startNum = strpos($controller, '.');
            if ($startNum !== false)
            {
                $controller = substr($controller, $startNum + 1);
            }
            $action = $this->request->action(); // 全小写

            $uri = $model . '.' . $controller . '.' . $action;
            $noCheckUri = [
                'miniapp.User.decodebindphone',    // 绑定手机号接口 小程序
                'miniapp.User.bindphone',    // 绑定手机号接口   手机号+验证码
                'miniapp.User.getphonecode',  //获取验证码接口
            ];  // 免绑手机号接口
            if (in_array($uri, $noCheckUri, true))
            {
                return true;
            } else
            {
                if ($headers['app-type'] === 'WEAPP' && $headers['version'] !== '1.0.0')
                {
                } else
                {
                    throw new ApiException('手机号未绑定', 200, 407);
                }
            }
        }
        // 账号模拟
        $simulation = config('app.simulation');

        if ($id !== $simulation['from'])
        {
            $map['id'] = $id;
        } else
        {
            $map['id'] = $simulation['to'] ?: $id;
            if ($map['id'] === $simulation['to'])
            {   // 模拟登陆
                $this->simulationLogin = true;
            }
        }

        $userinfo = (new User())->getUserinfo($map);

        $this->user = $userinfo;

        if (!$userinfo || empty($userinfo) || $userinfo['forbidden'] == 1) return false;

        /**
         * 定义全局常量 UID 方便日志打印带上用户ID信息
         */
        if (!defined('USERINFO_UID'))
        {
            define('USERINFO_UID', $userinfo['id']);
        }

        return true;
    }

    /**
     * 判断本次请求是否免登陆
     * @return bool
     */
    public function getIsExemptLogin(): bool
    {
        $model = $this->request->module();
        $controller = $this->request->controller();
        $startNum = strpos($controller, '.');
        if ($startNum !== false)
        {
            $controller = substr($controller, $startNum + 1);
        }
        $action = $this->request->action(); // 全小写

        $uri = $model . '.' . $controller . '.' . $action;

        $exemptLoginUri = [
            'miniapp.User.bindphone',
            'miniapp.User.getphonecode',
            'miniapp.User.recodeaddoredit',
            'miniapp.Index.index',
            'miniapp.Order.commonordercheck',//下单检查接口
            'miniapp.Fortune.fortuneindex',//月运首页接口
            'miniapp.AstrolabeController.index',//星盘-天象盘接口
            'miniapp.AstrolabeController.astrolabe_astrologer',//星盘-接口【占星师平台】
            'miniapp.AstrolabeController.astrologer_setting_index',//星盘-设置-接口【占星师平台】
            'miniapp.AstrolabeController.astrologer_setting_update',//星盘-设置-接口【占星师平台】
            'miniapp.AstrolabeController.astrologer_setting_restore',//星盘-设置-接口【占星师平台】
        ];

        if (in_array($uri, $exemptLoginUri, true))
        {
            return true;
        }
        return false;
    }


    /**
     * 加密字符串
     * @param string $data 字符串
     * @return string
     */
    protected function encryptWithOpenssl($data): string
    {
        $config = config('miniapp');
        return base64_encode(openssl_encrypt($data, $config['aes_method'], $config['aes_key'], OPENSSL_RAW_DATA, $config['aes_iv']));
    }

    /**
     * 解密字符串
     * @param string $data 字符串
     * @return string
     */
    protected function decryptWithOpenssl($data): string
    {
        $config = config('miniapp');
        return openssl_decrypt(base64_decode($data), $config['aes_method'], $config['aes_key'], OPENSSL_RAW_DATA, $config['aes_iv']);
    }
}
